From 68a8cffbc86b651bcf1ab95ea4a96fd67756cfad Mon Sep 17 00:00:00 2001 From: Tim Carey-Smith Date: Fri, 25 Jul 2014 16:05:27 -0700 Subject: [PATCH] ICE --- src/cargo/core/resolver.rs | 150 ++++++++++++++++++++--- src/cargo/ops/cargo_compile.rs | 2 +- src/cargo/ops/cargo_generate_lockfile.rs | 55 +++++---- 3 files changed, 167 insertions(+), 40 deletions(-) diff --git a/src/cargo/core/resolver.rs b/src/cargo/core/resolver.rs index 7971fbb77..5b4e81184 100644 --- a/src/cargo/core/resolver.rs +++ b/src/cargo/core/resolver.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::fmt; use serialize::{Encodable, Encoder}; +use serialize::{Encodable, Encoder, Decodable, Decoder}; use util::graph::{Nodes,Edges}; use core::{ @@ -21,15 +22,110 @@ pub struct Resolve { #[deriving(Encodable, Decodable, Show)] pub struct EncodableResolve { - package: Vec + package: Vec, + root: EncodableDependency } -#[deriving(Encodable, Decodable, Show)] -pub struct EncodableDependency{ +impl EncodableResolve { + pub fn to_resolve(&self, default: &SourceId) -> CargoResult { + let mut g = Graph::new(); + + add_pkg_to_graph(&mut g, &self.root, default); + + for dep in self.package.iter() { + add_pkg_to_graph(&mut g, dep, default); + } + + Ok(Resolve { graph: g, root: try!(self.root.to_package_id(default)) }) + } +} + +fn add_pkg_to_graph(g: &mut Graph, + dep: &EncodableDependency, + default: &SourceId) + -> CargoResult<()> +{ + let package_id = try!(dep.to_package_id(default)); + g.add(package_id.clone(), []); + + match dep.dependencies { + Some(ref deps) => { + for edge in deps.iter() { + g.link(package_id.clone(), try!(edge.to_package_id(default))); + } + }, + _ => () + }; + + Ok(()) +} + +#[deriving(Encodable, Decodable, Show, PartialOrd, Ord, PartialEq, Eq)] +pub struct EncodableDependency { + name: String, + version: String, + source: Option, + dependencies: Option> +} + +impl EncodableDependency { + fn to_package_id(&self, default_source: &SourceId) -> CargoResult { + PackageId::new( + self.name.as_slice(), + self.version.as_slice(), + self.source.as_ref().unwrap_or(default_source)) + } +} + +#[deriving(Show, PartialOrd, Ord, PartialEq, Eq)] +pub struct EncodablePackageId { name: String, version: String, - source: SourceId, - dependencies: Option> + source: Option +} + +impl> Encodable for EncodablePackageId { + fn encode(&self, s: &mut S) -> Result<(), E> { + let mut out = format!("{} {}", self.name, self.version); + self.source.as_ref().map(|s| { + out.push_str(format!(" ({})", s.to_url()).as_slice()) + }); + out.encode(s) + } +} + +impl> Decodable for EncodablePackageId { + fn decode(d: &mut D) -> Result { + let string: String = raw_try!(Decodable::decode(d)); + let regex = regex!(r"^([^ ]+) ([^ ]+) (?:\(([^\)]+)\))?$"); + let captures = regex.captures(string.as_slice()).expect("invalid serialized PackageId"); + + let name = captures.at(1); + let version = captures.at(2); + + let source = captures.at(3); + + let source_id = if source == "" { + None + } else { + Some(SourceId::from_url(source.to_string())) + }; + + Ok(EncodablePackageId { + name: name.to_string(), + version: version.to_string(), + source: source_id + }) + } +} + +impl EncodablePackageId { + fn to_package_id(&self, default_source: &SourceId) -> CargoResult { + PackageId::new( + self.name.as_slice(), + self.version.as_slice(), + self.source.as_ref().unwrap_or(default_source)) + } } impl> Encodable for Resolve { @@ -40,21 +136,39 @@ impl> Encodable for Resolve { let encodable = ids.iter().filter_map(|&id| { if self.root == *id { return None; } - let deps = self.graph.edges(id).map(|edge| { - let mut deps = edge.map(|e| e.clone()).collect::>(); - deps.sort(); - deps - }); - - Some(EncodableDependency { - name: id.get_name().to_string(), - version: id.get_version().to_string(), - source: id.get_source_id().clone(), - dependencies: deps - }) + Some(encodable_resolve_node(id, &self.graph)) }).collect::>(); - EncodableResolve { package: encodable }.encode(s) + EncodableResolve { + package: encodable, + root: encodable_resolve_node(&self.root, &self.graph) + }.encode(s) + } +} + +fn encodable_resolve_node(id: &PackageId, graph: &Graph) -> EncodableDependency { + let deps = graph.edges(id).map(|edge| { + let mut deps = edge.map(|e| { + encodable_package_id(e) + }).collect::>(); + deps.sort(); + deps + }); + + + EncodableDependency { + name: id.get_name().to_string(), + version: id.get_version().to_string(), + source: Some(id.get_source_id().clone()), + dependencies: deps, + } +} + +fn encodable_package_id(id: &PackageId) -> EncodablePackageId { + EncodablePackageId { + name: id.get_name().to_string(), + version: id.get_version().to_string(), + source: Some(id.get_source_id().clone()), } } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 84464ce90..367de1d15 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -100,7 +100,7 @@ pub fn compile(manifest_path: &Path, &PackageSet::new(packages.as_slice()), &resolve, &sources, &mut config)); } - //try!(ops::generate_lockfile(manifest_path, *shell, false)); + try!(ops::generate_lockfile(manifest_path, *shell, false)); let test_executables: Vec = targets.iter() .filter_map(|target| { diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index e68a93d71..9bea6159d 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -48,33 +48,22 @@ fn write_resolve(resolve: Resolve) { let mut e = Encoder::new(); resolve.encode(&mut e).unwrap(); - let deps = e.toml.find(&"package".to_string()).unwrap().as_slice().unwrap(); let mut out = String::new(); - for dep in deps.iter() { - let dep = dep.as_table().unwrap(); - out.push_str("[[package]]\n"); - out.push_str(format!("name = {}\n", lookup(dep, "name")).as_slice()); - out.push_str(format!("version = {}\n", lookup(dep, "version")).as_slice()); + let root = e.toml.find(&"root".to_string()).unwrap(); - dep.find(&"source".to_string()).map(|s| { - out.push_str(format!("source = {}\n", lookup(dep, "source")).as_slice()); - }); + println!("root={}", root); - dep.find(&"dependencies".to_string()).map(|s| { - let slice = s.as_slice().unwrap(); + out.push_str("[root]\n"); + emit_package(root.as_table().unwrap(), &mut out); - if !slice.is_empty() { - out.push_str("dependencies = [\n"); + let deps = e.toml.find(&"package".to_string()).unwrap().as_slice().unwrap(); - for child in s.as_slice().unwrap().iter() { - out.push_str(format!(" {},\n", child).as_slice()); - } + for dep in deps.iter() { + let dep = dep.as_table().unwrap(); - out.push_str("]\n"); - } - out.push_str("\n"); - }); + out.push_str("[[package]]\n"); + emit_package(dep, &mut out); } let mut file = File::create(&Path::new("Cargo.lock")); @@ -86,6 +75,30 @@ fn write_resolve(resolve: Resolve) { println!("{}", v); } +fn emit_package(dep: &TreeMap, out: &mut String) { + out.push_str(format!("name = {}\n", lookup(dep, "name")).as_slice()); + out.push_str(format!("version = {}\n", lookup(dep, "version")).as_slice()); + + dep.find(&"source".to_string()).map(|s| { + out.push_str(format!("source = {}\n", lookup(dep, "source")).as_slice()); + }); + + dep.find(&"dependencies".to_string()).map(|s| { + let slice = s.as_slice().unwrap(); + + if !slice.is_empty() { + out.push_str("dependencies = [\n"); + + for child in s.as_slice().unwrap().iter() { + out.push_str(format!(" {},\n", child).as_slice()); + } + + out.push_str("]\n"); + } + out.push_str("\n"); + }); +} + fn lookup<'a>(table: &'a TreeMap, key: &'static str) -> &'a toml::Value { - table.find(&key.to_string()).unwrap() + table.find(&key.to_string()).expect(format!("Didn't find {}", key).as_slice()) } -- 2.30.2